package ae.pcfc.cldos.online.common.facade.provider;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import ae.pcfc.cldos.online.common.clddb.domain.AppMetaData;
import ae.pcfc.cldos.online.common.clddb.domain.ApplicationAttachment;
import ae.pcfc.cldos.online.common.clddb.domain.ApplicationStatus;
import ae.pcfc.cldos.online.common.clddb.domain.MessageInbox;
import ae.pcfc.cldos.online.common.clddb.domain.ServiceMaster;
import ae.pcfc.cldos.online.common.clddb.domain.TaskMaster;
import ae.pcfc.cldos.online.common.clddb.domain.manager.AppMetaDataDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.ApplicationStatusDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.MessageInboxDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.ServiceMasterDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.TaskMasterDOM;
import ae.pcfc.cldos.online.common.etksdb.domain.User;
import ae.pcfc.cldos.online.common.etksdb.domain.manager.ClientDOM;
import ae.pcfc.cldos.online.common.etksdb.domain.manager.UserDomainObjectManager;
import ae.pcfc.cldos.online.common.facade.AdminTasksFacade;
import ae.pcfc.cldos.online.common.facade.BaseFacade;
import ae.pcfc.cldos.online.common.vo.AppMetaDataVO;
import ae.pcfc.cldos.online.common.vo.FileVO;
import ae.pcfc.cldos.online.common.vo.StatusVO;
import ae.pcfc.cldos.online.common.vo.UserInformationVO;
import ae.pcfc.cldos.online.common.vo.UserVO;
import ae.pcfc.cldos.online.common.vo.notifications.NotificationRequestParamsVO;
import ae.pcfc.cldos.online.common.vo.notifications.NotificationRequestVO;
import ae.pcfc.cldos.online.common.vo.notifications.NotificationVO;
import ae.pcfc.cldos.online.common.vo.notifications.NotificationsDbRestrictionsVO;
import ae.pcfc.cldos.online.common.vo.notifications.NotificationsVO;
import ae.pcfc.cldos.online.common.vo.tasks.AdminTaskVO;
import ae.pcfc.cldos.online.common.vo.tasks.TaskRequestDbRestrictions;
import ae.pcfc.cldos.online.common.vo.tasks.TaskRequestParamsVO;
import ae.pcfc.cldos.online.common.vo.tasks.TaskRequestVO;
import ae.pcfc.cldos.online.common.vo.tasks.TasksVO;

/**
 * 
 * @author arosa
 *
 */
public class AdminTasksFacadeImpl extends BaseFacade implements AdminTasksFacade {

	private UserDomainObjectManager userDomainObjectManager;
	private ApplicationStatusDOM applicationStatusDOM;
	private ClientDOM clientDOM;
	
	public ClientDOM getClientDOM() {
		return clientDOM;
	}

	public void setClientDOM(ClientDOM clientDOM) {
		this.clientDOM = clientDOM;
	}

	public ApplicationStatusDOM getApplicationStatusDOM() {
		return applicationStatusDOM;
	}

	public void setApplicationStatusDOM(ApplicationStatusDOM applicationStatusDOM) {
		this.applicationStatusDOM = applicationStatusDOM;
	}

	public void setUserDomainObjectManager(
			UserDomainObjectManager userDomainObjectManager) {
		this.userDomainObjectManager = userDomainObjectManager;
	}
	
	private TaskMasterDOM taskMasterDOM;
	
	public void setTaskMasterDOM(TaskMasterDOM taskMasterDOM) {
		this.taskMasterDOM = taskMasterDOM;
	}
	
	private ServiceMasterDOM serviceMasterDOM;
	
	public void setServiceMasterDOM(ServiceMasterDOM serviceMasterDOM) {
		this.serviceMasterDOM = serviceMasterDOM;
	}
	
	private MessageInboxDOM messageInboxDOM;
	
	public void setMessageInboxDOM(MessageInboxDOM messageInboxDOM) {
		this.messageInboxDOM = messageInboxDOM;
	}
	
	private AppMetaDataDOM appMetaDataDOM;
	
	public void setAppMetaDataDOM(AppMetaDataDOM appMetaDataDOM) {
		this.appMetaDataDOM = appMetaDataDOM;
	}
	
	@Transactional
	public AppMetaDataVO getPlainAppMetaDataVO(String appId) throws Exception{
		AppMetaData appMetaData = appMetaDataDOM.getPlainAppMetaDataById(appId);
		AppMetaDataVO appMetaDataVO = null;
		if(appMetaData!=null){
			appMetaDataVO = new AppMetaDataVO();
			getMapper().map(appMetaData, appMetaDataVO);
		}
		return appMetaDataVO;
	}
	
	@SuppressWarnings("unchecked")
	@Transactional
	public TasksVO getAdminTaskList(TaskRequestVO taskRequestVO){
		
		TasksVO tasksVO = new TasksVO();
		
		UserVO userVO = taskRequestVO.getUserVO();
		
		tasksVO.setAdminTaskVOs((List<AdminTaskVO>)Collections.EMPTY_LIST);
		tasksVO.setTotal(0);
		
		
		String userName = userVO.getUsername();
		User user = userDomainObjectManager.findUserByUserName(userName);
		Long clientId = user.getClientId();
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setClientId(clientId);
		userInformationVO.setAdmin(userVO.isAdmin());
		userInformationVO.setUserId(user.getUId());
		
		TaskRequestParamsVO taskRequestParamsVO = taskRequestVO.getTaskRequestParamsVO();
		TaskRequestDbRestrictions taskRequestDbRestrictions = new TaskRequestDbRestrictions();
		getMapper().map(taskRequestParamsVO, taskRequestDbRestrictions);
		
		
		taskRequestDbRestrictions.setRefNo(taskRequestParamsVO.getReferenceNo());
		
		String  serviceName = taskRequestParamsVO.getServiceName();
		if(serviceName!=null && !serviceName.isEmpty()){
			ServiceMaster serviceMaster = serviceMasterDOM.findServiceMasterByName(serviceName);
			if(serviceMaster!=null){
				taskRequestDbRestrictions.setServiceId(serviceMaster.getServiceCode());
			}else {
				return tasksVO;
			}
		}
		
		String  taskName = taskRequestParamsVO.getTaskName();
		if(taskName!=null && !taskName.isEmpty()){
			TaskMaster taskMaster = taskMasterDOM.findTaskMasterByName(taskName);
			if(taskMaster!=null){
				taskRequestDbRestrictions.setTaskId(taskMaster.getTaskCode());
			} else {
				return tasksVO;
			}
		}
		
		String statusCode = taskRequestParamsVO.getStatus();
		if(statusCode!=null && !statusCode.isEmpty()){
			Long statusId = null;
			try{
				statusId = Long.parseLong(statusCode);
			} catch (NumberFormatException e) {
				return tasksVO;
			}
			taskRequestDbRestrictions.setStatusId(statusId);
		}
		
		List<MessageInbox> messageInboxList = messageInboxDOM.getUserTasks(userInformationVO, taskRequestDbRestrictions);
		if(messageInboxList.size()>0){
			List<AdminTaskVO> adminTaskVOs = new ArrayList<AdminTaskVO>();
		
			for(MessageInbox messageInbox : messageInboxList){
				AdminTaskVO adminTaskVO = new AdminTaskVO();
				AppMetaData appMetaData = messageInbox.getAppMetaData();
				adminTaskVO.setAppId(appMetaData.getApplicationId());
				adminTaskVO.setDate(messageInbox.getMiSentOn());
				adminTaskVO.setReferenceNo(appMetaData.getClientRefNo());
				adminTaskVO.setServiceNameEn(appMetaData.getServiceMaster().getServiceName());
				//abed
				adminTaskVO.setServiceCode(appMetaData.getServiceMaster().getServiceCode());
				adminTaskVO.setStatus(appMetaData.getApplicationStatus().getStatusDesc());
				//abed
				adminTaskVO.setStatusCode(appMetaData.getApplicationStatus().getStatusCode());
				adminTaskVO.setTaskNameEn(messageInbox.getTaskMaster().getTaskName());
				//abed
				adminTaskVO.setTaskCode(messageInbox.getTaskMaster().getTaskCode());
				adminTaskVOs.add(adminTaskVO);
			}
			tasksVO.setAdminTaskVOs(adminTaskVOs);
			tasksVO.setTotal(messageInboxDOM.getTasksCount(userInformationVO, taskRequestDbRestrictions));
		}
		
		
		return tasksVO;
	}
	
	@SuppressWarnings("unchecked")
	@Transactional
	public NotificationsVO getUserNotifications(NotificationRequestVO notificationRequestVO){
		
		NotificationsVO notificationsVO = new NotificationsVO();
		
		notificationsVO.setNotificationVOs((List<NotificationVO>)Collections.EMPTY_LIST);
		notificationsVO.setTotal(0);
		
		UserVO userVO = notificationRequestVO.getUserVO();
		NotificationRequestParamsVO notificationRequestParamsVO = notificationRequestVO.getNotificationRequestParamsVO();
		
		String userName = userVO.getUsername();
		User user = userDomainObjectManager.findUserByUserName(userName);
		Long clientId = user.getClientId();
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setClientId(clientId);
		userInformationVO.setAdmin(userVO.isAdmin());
		userInformationVO.setUserId(user.getUId());
		
		NotificationsDbRestrictionsVO notificationsDbRestrictionsVO = new NotificationsDbRestrictionsVO();
		getMapper().map(notificationRequestParamsVO, notificationsDbRestrictionsVO);
		
		String refNo = notificationRequestParamsVO.getReferenceNo();
		notificationsDbRestrictionsVO.setRefNo(refNo);
		
		String notificationId = notificationRequestParamsVO.getNotificationId();
		if(notificationId!=null && !notificationId.isEmpty()){
			try{
				Long mesId = Long.parseLong(notificationId);
				notificationsDbRestrictionsVO.setMesId(mesId);
			} catch (NumberFormatException e) {
				return notificationsVO;
			}
		}
		
		String serviceName = notificationRequestParamsVO.getServiceName();
		if(serviceName!=null && !serviceName.isEmpty()){
			ServiceMaster serviceMaster = serviceMasterDOM.findServiceMasterByName(serviceName);
			if(serviceMaster!=null){
				notificationsDbRestrictionsVO.setServiceId(serviceMaster.getServiceCode());
			} else {
				return notificationsVO;
			}
		}
		
		List<MessageInbox> messageInboxs = messageInboxDOM.getUserNotifications(userInformationVO, 
				notificationsDbRestrictionsVO);
		if(messageInboxs.size()>0){
			List<NotificationVO> notificationVOs = new ArrayList<NotificationVO>();
			for(MessageInbox messageInbox : messageInboxs){
				NotificationVO notificationVO = new NotificationVO();
				notificationVO.setApplicationId(messageInbox.getAppId().toString());
				notificationVO.setClientRefNo(messageInbox.getAppMetaData().getClientRefNo());
				notificationVO.setDate(messageInbox.getMiSentOn());
				notificationVO.setNotificationId(messageInbox.getMiMsgId().toString());
				notificationVO.setServiceName(messageInbox.getAppMetaData().getServiceMaster().getServiceName());
				//abed
				notificationVO.setServiceCode(messageInbox.getAppMetaData().getServiceMaster().getServiceCode());
				notificationVO.setSubject(messageInbox.getMiSubject());
				notificationVO.setDetails(messageInbox.getMiDtls());
				notificationVO.setSubjectAr(messageInbox.getMiSubjectAr());
				notificationVO.setDetailsAr(messageInbox.getMiDtlsAr());
				if(messageInbox.getMiActionFlag().equals(MessageInbox.MESSAGE_ACTION_FLAG_NOT_DONE)){
					notificationVO.setUnreaded(true);
				}
				if(messageInbox.getApplicationAttachments()!=null){
					List<FileVO> files = new ArrayList<FileVO>();
					for(ApplicationAttachment applicationAttachment : messageInbox.getApplicationAttachments()){
						FileVO fileVO = new FileVO();
						fileVO.setFileName(applicationAttachment.getAttachmentFileName());
						fileVO.setFileExt(applicationAttachment.getAttachmentFileExt());
						fileVO.setId(applicationAttachment.getAttachmentId());
						files.add(fileVO);
					}
					notificationVO.setFileVOs(files);
				}
				notificationVOs.add(notificationVO);
				
				
			}
			notificationsVO.setNotificationVOs(notificationVOs);
			notificationsVO.setTotal(messageInboxDOM.getTotalNotifications(userInformationVO, notificationsDbRestrictionsVO));
		}
		return notificationsVO;
	}
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.common.facade.AdminTasksFacade#getAllAppRequests(ae.pcfc.cldos.online.common.vo.tasks.TaskRequestVO)
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public TasksVO getAllAppRequests(TaskRequestVO taskRequestVO){
		TasksVO tasksVO = new TasksVO();
		UserVO userVO = taskRequestVO.getUserVO();
		tasksVO.setAdminTaskVOs((List<AdminTaskVO>)Collections.EMPTY_LIST);
		tasksVO.setTotal(0);
		
		String userName = userVO.getUsername();
		User user = userDomainObjectManager.findUserAndClientByUserName(userName);
		Long clientId = user.getClientId();
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setClientId(clientId);
		
		TaskRequestParamsVO taskRequestParamsVO = taskRequestVO.getTaskRequestParamsVO();
		TaskRequestDbRestrictions taskRequestDbRestrictions = new TaskRequestDbRestrictions();
		getMapper().map(taskRequestParamsVO, taskRequestDbRestrictions);
		
		
		taskRequestDbRestrictions.setRefNo(taskRequestParamsVO.getReferenceNo());
		
		String  serviceName = taskRequestParamsVO.getServiceName();
		if(serviceName!=null && !serviceName.isEmpty()){
			ServiceMaster serviceMaster = serviceMasterDOM.findServiceMasterByName(serviceName);
			if(serviceMaster!=null){
				taskRequestDbRestrictions.setServiceId(serviceMaster.getServiceCode());
			}else {
				return tasksVO;
			}
		}
		
		String statusCode = taskRequestParamsVO.getStatus();
		if(statusCode!=null && !statusCode.isEmpty()){
			Long statusId = null;
			try{
				statusId = Long.parseLong(statusCode);
			} catch (NumberFormatException e) {
				return tasksVO;
			}
			taskRequestDbRestrictions.setStatusId(statusId);
		}
		List<AppMetaData> allAppRequests = appMetaDataDOM.getAllAppRequests(userInformationVO, taskRequestDbRestrictions);
		if(allAppRequests.size()>0){
			List<AdminTaskVO> adminTaskVOs = new ArrayList<AdminTaskVO>();
			for(AppMetaData appMetaData : allAppRequests){
				AdminTaskVO adminTaskVO = new AdminTaskVO();
				adminTaskVO.setAppId(appMetaData.getApplicationId());
				adminTaskVO.setDate(appMetaData.getApplicationDate());
				adminTaskVO.setReferenceNo(appMetaData.getClientRefNo());
				adminTaskVO.setServiceNameEn(appMetaData.getServiceMaster().getServiceName());
				//abed
				adminTaskVO.setServiceCode(appMetaData.getServiceMaster().getServiceCode());
				adminTaskVO.setStatus(appMetaData.getApplicationStatus().getStatusDesc());
				//abed
				adminTaskVO.setStatusCode(appMetaData.getApplicationStatus().getStatusCode());
				adminTaskVOs.add(adminTaskVO);
			}
			tasksVO.setAdminTaskVOs(adminTaskVOs);
			tasksVO.setTotal(appMetaDataDOM.getApplicationCount(userInformationVO, taskRequestDbRestrictions));
		}
		return tasksVO;
	}
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.common.facade.AdminTasksFacade#getAllAppRequests(ae.pcfc.cldos.online.common.vo.tasks.TaskRequestVO)
	 */
	/**
	 * @param taskRequestVO
	 * @param clientId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public TasksVO getAllAppRequestsForTksAdmin(TaskRequestVO taskRequestVO,String tksId){
		TasksVO tasksVO = new TasksVO();
		tasksVO.setAdminTaskVOs((List<AdminTaskVO>)Collections.EMPTY_LIST);
		tasksVO.setTotal(0);
		
		UserInformationVO userInformationVO = new UserInformationVO();
		if(tksId!=null){
			Long clientId = clientDOM.getClientIdByTrakheesId(tksId);
			userInformationVO.setClientId(clientId);
		}
		
		TaskRequestParamsVO taskRequestParamsVO = taskRequestVO.getTaskRequestParamsVO();
		TaskRequestDbRestrictions taskRequestDbRestrictions = new TaskRequestDbRestrictions();
		getMapper().map(taskRequestParamsVO, taskRequestDbRestrictions);
		
		
		taskRequestDbRestrictions.setRefNo(taskRequestParamsVO.getReferenceNo());
		
		String  serviceName = taskRequestParamsVO.getServiceName();
		if(serviceName!=null && !serviceName.isEmpty()){
			ServiceMaster serviceMaster = serviceMasterDOM.findServiceMasterByName(serviceName);
			if(serviceMaster!=null){
				taskRequestDbRestrictions.setServiceId(serviceMaster.getServiceCode());
			}else {
				return tasksVO;
			}
		}
		
		String statusCode = taskRequestParamsVO.getStatus();
		if(statusCode!=null && !statusCode.isEmpty()){
			Long statusId = null;
			try{
				statusId = Long.parseLong(statusCode);
			} catch (NumberFormatException e) {
				return tasksVO;
			}
			taskRequestDbRestrictions.setStatusId(statusId);
		}
		List<AppMetaData> allAppRequests = appMetaDataDOM.getAllAppRequests(userInformationVO, taskRequestDbRestrictions);
		if(allAppRequests.size()>0){
			List<AdminTaskVO> adminTaskVOs = new ArrayList<AdminTaskVO>();
			for(AppMetaData appMetaData : allAppRequests){
				AdminTaskVO adminTaskVO = new AdminTaskVO();
				adminTaskVO.setAppId(appMetaData.getApplicationId());
				adminTaskVO.setDate(appMetaData.getApplicationDate());
				adminTaskVO.setReferenceNo(appMetaData.getClientRefNo());
				adminTaskVO.setServiceNameEn(appMetaData.getServiceMaster().getServiceName());
				adminTaskVO.setStatus(appMetaData.getApplicationStatus().getStatusDesc());
				adminTaskVOs.add(adminTaskVO);
			}
			tasksVO.setAdminTaskVOs(adminTaskVOs);
			tasksVO.setTotal(appMetaDataDOM.getApplicationCount(userInformationVO, taskRequestDbRestrictions));
		}
		return tasksVO;
	}
	/**
	 * @param msgId
	 * @return
	 * Method to get the message details from db
	 */
	@Transactional
	public NotificationVO getNotificationDetail(Long msgId){
		MessageInbox messageInbox = messageInboxDOM.getNotificationDetail(msgId);
		NotificationVO notificationVO = new NotificationVO();
		notificationVO.setApplicationId(messageInbox.getAppId().toString());
		notificationVO.setClientRefNo(messageInbox.getAppMetaData().getClientRefNo());
		notificationVO.setDate(messageInbox.getMiSentOn());
		notificationVO.setNotificationId(messageInbox.getMiMsgId().toString());
		notificationVO.setServiceName(messageInbox.getAppMetaData().getServiceMaster().getServiceName());
		//abed
		notificationVO.setServiceCode(messageInbox.getAppMetaData().getServiceMaster().getServiceCode());
		notificationVO.setSubject(messageInbox.getMiSubject());
		notificationVO.setDetails(messageInbox.getMiDtls());
		notificationVO.setSubjectAr(messageInbox.getMiSubjectAr());
		notificationVO.setDetailsAr(messageInbox.getMiDtlsAr());
		if(messageInbox.getMiActionFlag().equals(MessageInbox.MESSAGE_ACTION_FLAG_NOT_DONE)){
			notificationVO.setUnreaded(true);
		}
		List<FileVO> files = new ArrayList<FileVO>();
		for(ApplicationAttachment applicationAttachment : messageInbox.getApplicationAttachments()){
			FileVO fileVO = new FileVO();
			fileVO.setFileName(applicationAttachment.getAttachmentFileName());
			fileVO.setFileExt(applicationAttachment.getAttachmentFileExt());
			fileVO.setId(applicationAttachment.getAttachmentId());
			files.add(fileVO);
		}
		notificationVO.setFileVOs(files);
		
		return notificationVO;
	}
	/**
	 * @param statusType
	 * @return List<StatusVO>
	 * Method to get the application status
	 */
	@Transactional
	public List<StatusVO> findApplicationStatusByType(String statusType){
		List<StatusVO> statusVoList = new ArrayList<StatusVO>();
		List<ApplicationStatus> statusList = applicationStatusDOM.findApplicationStatusByType(statusType);
		if(statusList!=null && statusList.size()!=0){
			for(ApplicationStatus appStatus : statusList){
				StatusVO statusVO = new StatusVO();
				statusVO.setStatusCode(appStatus.getStatusCode().toString());
				statusVO.setStatusDesc(appStatus.getStatusDesc());
				statusVoList.add(statusVO);
			}
		}
		return statusVoList;
	}
	
	@Transactional
	public Integer getNewNotificationsCount(UserVO userVO){
		User user = userDomainObjectManager.findUserByUserName(userVO.getUsername());
		
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setAdmin(userVO.isAdmin());
		userInformationVO.setClientId(user.getClientId());
		userInformationVO.setUserId(user.getUId());
		
		return messageInboxDOM.getNewNotificationsCount(userInformationVO);
	}
	
	@Transactional
	public Integer getNewTasksCount(UserVO userVO){
		User user = userDomainObjectManager.findUserByUserName(userVO.getUsername());
		
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setAdmin(userVO.isAdmin());
		userInformationVO.setClientId(user.getClientId());
		userInformationVO.setUserId(user.getUId());
		
		return messageInboxDOM.getNewTaskCount(userInformationVO);
	}
	
	@Transactional
	public void markNotificationAsReaded(String mesId, UserVO userVO){
		Long messageId = null;
		try{
			messageId = Long.parseLong(mesId);
		}catch (Exception e) {}
		
		User user = userDomainObjectManager.findUserByUserName(userVO.getUsername());
		if(user==null || messageId==null) return;
		
		UserInformationVO userInformationVO = new UserInformationVO();
		userInformationVO.setAdmin(userVO.isAdmin());
		userInformationVO.setClientId(user.getClientId());
		userInformationVO.setUserId(user.getUId());
		
		messageInboxDOM.markNotificationAsReaded(messageId, userInformationVO);
	}
}
